package ccm.tools.Label;

import ccm.component.image.AutoResizeableImageJPanel;
import ccm.component.image.ImageEvent;
import ccm.component.image.ImageJPanelListener;
import ccm.component.override.JLabel;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Scanner;

public abstract class PointLabelJPanel extends LabelJPanel implements ImageJPanelListener
{
    static private final Color[] colors=new Color[]{
            Color.RED,Color.YELLOW,Color.BLUE,Color.MAGENTA,Color.ORANGE,Color.GREEN,Color.PINK,Color.LIGHT_GRAY,new Color(0XD3,0X61,0X35),new Color(112,152,95),new Color(86,81,55),new Color(0XE6,0Xaa,0X68),

            new Color(0X99,0X33,0XFF),new Color(0X00,0X99,0X99),new Color(0X99,0X99,0X33),new Color(114,234,47),new Color(245,7,115),new Color(0X00,0X66,0X33),new Color(0X99,0XCC,0X33),new Color(0XCC,0X66,0X99),
    };
    protected final AutoResizeableImageJPanel originImageJPanel;
    protected final JLabel pointsJLabel;
    protected final Point[] points;
    protected int pointsCnt=0;


    protected PointLabelJPanel(SubsetInfo subsetInfo,int n)
    {
        super(subsetInfo);
        points=new Point[n];

        mainJPanel.setLayout(new GridLayout(1,2));
        mainJPanel.add(originImageJPanel=new AutoResizeableImageJPanel());
        originImageJPanel.addImageListener(this);
        originImageJPanel.setResizeRate(16);

        add(pointsJLabel=new JLabel(),BorderLayout.SOUTH);

        imgId=displayOne(imgId);
        setVisible(true);
    }

    protected int displayOne(int imgId)
    {
        load(imgId);
        return displayOnly(imgId);
    }

    public void load(int imgId)
    {
        imgId=Math.min(Math.max(imgId,subsetInfo.getImageFirst()),subsetInfo.getImageLast());
        Arrays.fill(points,new Point(-1,-1));
        pointsCnt=0;
        try
        {
            Scanner scanner=new Scanner(new File(subsetInfo.getDir()+"/image"+imgId+".nts"));
            for(;pointsCnt<points.length;++pointsCnt)
            {points[pointsCnt]=new Point(scanner.nextInt(),scanner.nextInt());}
        }catch(IOException|NoSuchElementException ex)
        {
            ex.printStackTrace();
        }
    }

    protected int displayOnly(int imgId)
    {
        imgId=Math.min(Math.max(imgId,subsetInfo.getImageFirst()),subsetInfo.getImageLast());
        try
        {
            imgIdJSpinner.setValue(imgId);
            System.out.println("imgId:"+imgId);
            BufferedImage originImage=new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB),null).filter(ImageIO.read(new File(subsetInfo.getDir()+"/image"+imgId+".bmp")),null);

            for(int i=0;i<points.length;++i)
            {
                if(points[i].getX()>=0&&points[i].getY()>=0)
                {originImage.setRGB(points[i].getX(),points[i].getY(),getColor(i).getRGB());}
            }

            originImageJPanel.setImage(originImage);
            pointsJLabel.setText(Arrays.toString(points));
        }catch(IOException e)
        {
            JOptionPane.showMessageDialog(null,"缺少文件","错误",JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
            System.exit(0);
        }
        return imgId;
    }

    Color getColor(int i)
    {
        return colors[i%colors.length];
    }

    public void imageClicked(ImageEvent e)
    {
        if(pointsCnt>=points.length)
        {
            pointsCnt=0;
            Arrays.fill(points,new Point(-1,-1));
        }
        points[pointsCnt]=new Point(e.getX(),e.getY());
        ++pointsCnt;
        if(pointsCnt==points.length)
        {save();}
        displayOnly(imgId);
    }

    public void save()
    {
        try
        {
            BufferedWriter out=new BufferedWriter(new FileWriter(subsetInfo.getDir()+"/image"+imgId+".nts"));
            for(Point point: points)
            {out.write(point.getX()+" "+point.getY()+"\n");}
            out.close();
            System.out.println(Arrays.toString(points));
        }catch(IOException ex)
        {
            ex.printStackTrace();
        }
    }
}
